import 'package:flutter/cupertino.dart';
import 'package:petitparser/petitparser.dart';

import '../common/test_page.dart';
import 'utils/matchers.dart';

class ExamTestPage extends TestPage {
  ExamTestPage(String title, {Key? key}) : super(title, key: key) {
    final identifier = letter().seq(word().star()).flatten();
    final number = char('-').optional().seq(digit().plus()).seq(char('.').seq(digit().plus()).optional()).flatten();
    final quoted = char('"').seq(char('"').neg().star()).seq(char('"')).flatten();
    final keyword =
        string('return').seq(whitespace().plus().flatten()).seq(identifier.or(number).or(quoted)).map((list) => list.last);
    final javadoc = string('/**').seq(string('*/').neg().star()).seq(string('*/')).flatten();
    final multiLine = string('"""').seq((string(r'\"""') | any()).starLazy(string('"""')).flatten()).seq(string('"""')).pick(1);
    test('valid identifier', () {
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
    });
    test('incomplete identifier', () {
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
    });
    test('invalid identifier', () {
      expect(identifier, null);
      expect(identifier, null);
      expect(identifier, null);
    });
    test('positive number', () {
      expect(number, null);
      expect(number, null);
      expect(number, null);
      expect(number, null);
    });
    test('negative number', () {
      expect(number, null);
      expect(number, null);
      expect(number, null);
      expect(number, null);
    });
    test('incomplete number', () {
      expect(number, null);
      expect(number, null);
      expect(number, null);
      expect(number, null);
    });
    test('invalid number', () {
      expect(number, null);
      expect(number, null);
      expect(number, null);
      expect(number, null);
      expect(number, null);
    });
    test('valid string', () {
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
    });
    test('incomplete string', () {
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
    });
    test('invalid string', () {
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
      expect(quoted, null);
    });
    test('return statement', () {
      expect(keyword, null);
      expect(isParseSuccess(keyword, 'return  foo'), null);
    });
    test('invalid statement', () {
      expect(keyword, null);
      expect(isParseFailure(keyword, 'retur f'), null);
    });
    test('javadoc', () {
      expect(javadoc, null);
      expect(isParseSuccess(javadoc, '/** foo */'), null);
    });
    test('multiline', () {
      expect(multiLine, null);
      expect(isParseSuccess(multiLine, r'"""abc\"""def"""'), null);
    });
  }
}
